"""
向消息队列中发送任务，并将子节点执行结果输出
"""
import json
import threading
import time

import pika
import uuid
from concurrent.futures import ThreadPoolExecutor, as_completed
from settings import rabbitmq_host, rabbitmq_username, rabbitmq_password, rabbitmq_queue_name, rabbitmq_port


class CommanderRpcClient(object):
    def __init__(self):
        self.credentials = pika.PlainCredentials(username=rabbitmq_username, password=rabbitmq_password)
        self.connection = pika.BlockingConnection(
            pika.ConnectionParameters(
                host=rabbitmq_host,
                port=rabbitmq_port,
                credentials=self.credentials
            )
        )
        self.channel = self.connection.channel()
        result = self.channel.queue_declare(queue="", exclusive=True)
        self.callback_queue = result.method.queue

        self.channel.basic_consume(
            queue=self.callback_queue,
            on_message_callback=self.on_response,
            auto_ack=True,
        )

    def on_response(self, ch, method, props, body):
        if self.corr_id == props.correlation_id:
            self.response = body
            print(body)

    def scan(self, ip, port):
        ip = str(ip)
        port = str(port)
        self.response = None
        self.corr_id = str(uuid.uuid4())
        self.channel.basic_publish(
            exchange="",
            routing_key=rabbitmq_queue_name,
            properties=pika.BasicProperties(
                reply_to=self.callback_queue,
                correlation_id=self.corr_id,
            ),
            body=json.dumps({
                "IP": ip,
                "PORT": port,
            }).encode("utf8")
        )
        print(f"Send {ip}:{port}")
        return self
        # print(self.response)
        # return self.response


if __name__ == '__main__':
    threads = 100
    port = 22
    commander = CommanderRpcClient()
    # ip = "192.168.1.102"
    # for port in range(1, 1000):
    #     _ = threading.Thread(target=commander.scan, args=(ip, port))
    #     _.start()

    # with ThreadPoolExecutor(max_workers=threads) as t:
    #     tasks = []
    #     for port in range(1, 1000):
    #         target = {"ip": ip, "port": port}
    #         # _ = t.submit(commander.scan, **target)
    #         _ = t.submit(test, port)
    #         tasks.append(_)
    #         # t.submit(test, port)
    #     # for task in tasks:
    #     #
    #     for future in as_completed(tasks):
    #         data = future.result()
    #         print(data)


    # ip = input("IP:")
    ip = "192.168.1.102"
    # port = input("Port:")
    # print(f"[+] Sent {ip}:{port} to Rabbitmq")
    tasks = []
    for port in range(1, 1000):
        # response = commander.scan(ip, port)
        # print(f"[+] {response.decode('utf8')}")
        tasks.append(commander.scan(ip, port))
    # print("-"*30)
    for task in tasks:
        while True:
            if task.response is None:
                task.connection.process_data_events()
            else:
                print(task.response)
                break
